# -*- coding:utf-8 -*-
import codecs
import configparser
import random
import pika
import time
import json
import threading
import requests
import os
import logging
import argparse
import emoji
from logging.handlers import RotatingFileHandler
from datetime import datetime


# config file
parser = argparse.ArgumentParser(description='IDMI rabbit message queue consumer')
parser.add_argument('--log_path',
                    type=str,
                    help='log_path',
                    default=os.getenv('log_path', './log/rabbitmq_consumer_log.log'),
                    required=False)
parser.add_argument('--settings_path',
                    type=str,
                    help='settings_path',
                    default=os.getenv('settings_path', './settings.cfg'),
                    required=False)
parser.add_argument('--idmi_backend_consumer_URI',
                    type=str,
                    help='idmi_backend_consumer_URI',
                    default=os.getenv('idmi_backend_consumer_URI', 'http://backend.idmiclub.info/tickets/store/store_ticket'),
                    required=False)
args = parser.parse_args()

# ##########LOG############
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')

def setRotatingRootLogger(filename, level=logging.INFO):
    handler = RotatingFileHandler(filename,
                                  encoding='UTF-8',
                                  maxBytes=1000000,
                                  backupCount=5)
    handler.setFormatter(formatter)
    logger = logging.getLogger()
    logger.setLevel(level)
    logger.addHandler(handler)

# TODO 
# setRotatingRootLogger(filename=args.log_path)

# ##########SETTINGS############
class CustomConfigParser(configparser.ConfigParser):
    def __init__(self):
        super().__init__()

    def read_config(self, filename):
        super().read(filename, encoding='utf-8')
        d = dict(self._sections)
        for k in d:
            d[k] = dict(self._defaults, **d[k])
            for j in d[k]:
                if '\n' in d[k][j]:
                    d[k][j] = [item for item in d[k][j].strip().split('\n')]
                d[k].pop('__name__', None)
        return d

def getConfigFromConfigfile(file):
    configParser = CustomConfigParser()
    return configParser.read_config(file)

settings = getConfigFromConfigfile(args.settings_path)




class RabbitMQ_Consumer_class:

    def __init__(self):
        self.login = pika.PlainCredentials(
            username=os.getenv('RabbitMQ_username', settings['Rabbit_MQ']['user']),
            password=os.getenv('RabbitMQ_password', settings['Rabbit_MQ']['pw'])
        )
        self.connection_parameter = pika.ConnectionParameters(
            host=os.getenv('RabbitMQ_host', settings['Rabbit_MQ']['ip']),
            port=os.getenv('RabbitMQ_port', settings['Rabbit_MQ']['data_port']),
            virtual_host=os.getenv('RabbitMQ_virtual_host', settings['Rabbit_MQ']['vhost']),
            credentials=self.login,
            connection_attempts=int(os.getenv('CONNECTION_ATTEMPTS', settings['Rabbit_MQ']['connection_attempts'])),
            retry_delay=int(os.getenv('RETRY_DELAY', settings['Rabbit_MQ']['retry_delay'])),
            heartbeat=0
        )
        self.connection = None
        self.channel = None
        # self.publish_url = os.getenv('BACKEND_BASE_URI', settings['Backend_Server']['base_uri']) + \
        # 				   os.getenv('BACKEND_ADD_URI', settings['Backend_Server']['add_uri'])
        self.publish_url = args.idmi_backend_consumer_URI

    def connect(self):
        if not self.connection or self.connection.is_closed:
            self.connection = pika.BlockingConnection(self.connection_parameter)
            self.channel = self.connection.channel()
            self.channel.exchange_declare(
                exchange=os.getenv('RABBITMQ_EXCHANGE', settings['Rabbit_MQ']['exchange']),
            )
            result = self.channel.queue_declare(
                queue=os.getenv('RABBITMQ_QUEUE', settings['Rabbit_MQ']['queue']),
                # durable=True, auto_delete=False
            )
            self.channel.queue_bind(exchange=os.getenv('RABBITMQ_EXCHANGE', settings['Rabbit_MQ']['exchange']),
                                    queue=result.method.queue)

    def callback(self, channel, method_frame, header_frame, body):
        time.sleep(0.2)
        body = body.decode('utf-8')
        body = json.loads(body, encoding='utf-8')
        self.preprocess_body(body, channel, method_frame)
        logging.info(msg="INFO : preprocess the article, TIME is ：{TIME}".format(
            TIME=str(datetime.now()))
        )


    def connect_thread_func(self):
        while True:
            time.sleep(0.1)
            self.connection.process_data_events()

    def consumer(self):
        print('start consuming')
        self.connect()
        connect_thread = threading.Thread(
            target=self.connect_thread_func
        )
        connect_thread.start()
        logging.info(msg="INFO : start collect articles .... ")
        self.channel.basic_consume(
            queue=os.getenv('RABBITMQ_QUEUE', settings['Rabbit_MQ']['queue']),
            on_message_callback=self.callback,
            auto_ack=False,
        )
        self.channel.start_consuming()

    def preprocess_body(self, body, channel, method_frame):
        time.sleep(0.5)
        response = self.publish_msg(msg=body,
                                    channel=channel,
                                    method_frame=method_frame)





        # if not response.status_code == 200:
        #     channel.basic_nack(delivery_tag=method_frame.delivery_tag)
        #     logging.error(msg="ERROR : Backend Error Code {ERROR_CODE}".format(
        #         ERROR_CODE=response.status_code)
        #     )
        # else:
        #     # 这里完全先不消耗数据
        #     channel.basic_ack(delivery_tag=method_frame.delivery_tag)
        #     logging.info("INFO : collect one article in {TIME}".format(
        #         TIME=str(datetime.now())
        #     ))

    def publish_msg(self, msg, channel, method_frame):
        sourceId = msg['sourceId']
        print(msg)
        with codecs.open(filename='./temp/' + sourceId + '.txt',
                         mode='a', encoding='utf-8') as fa:
            fa.write(json.dumps(msg, ensure_ascii=False))
            fa.write('\r\n')
        channel.basic_ack(delivery_tag=method_frame.delivery_tag)


        # sourceId = msg['sourceId']
        # source_web_origin = msg['source_web_origin']
        # source_language = msg['source_language']
        # market = msg['market']
        # url = msg['url']
        # _url_unique = msg['_url_unique']
        # title = msg['title'] if isinstance(msg['title'], str) else ''
        # text = msg['text'] if isinstance(msg['text'], str) else ''
        # title = emoji.demojize(title)
        # text = emoji.demojize(text)
        #
        # model_en = msg['model_en']
        # model_src = msg['model_src']
        # oem_src = msg['oem_src']
        # add_info = msg['add_info']
        # data = dict(
        #     sourceId=sourceId,
        #     source_web_origin=source_web_origin,
        #     source_language=source_language,
        #     market=market,
        #     url=url,
        #     _url_unique=_url_unique,
        #     title=title,
        #     text=text,
        #     model_en=model_en,
        #     model_src=model_src,
        #     oem_src=oem_src,
        #     add_info=add_info,
        # )
        # with codecs.open(filename='test.txt', mode='a', encoding='utf-8') as fa:
        #     fa.write(json.dumps(data, ensure_ascii=False))
        #     fa.write('\r\n')
        # return requests.post(
        #     url=self.publish_url,
        #     data=data
        # )


rabbit_mq_object = RabbitMQ_Consumer_class()
rabbit_mq_object.consumer()
